/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.metasketch.model.loader.links;

import java.util.Collection;
import java.util.HashSet;

import org.metasketch.model.loader.GraphNode;
import org.metasketch.model.loader.IGetLinkLogic;

/**
 * 
 * @author guilhermegrg
 */
public class ParticipationMapLinkProvider extends IGetLinkLogic {

	@Override
	public boolean canProcess(GraphNode node, String type, String targetType) {
		if (type.equalsIgnoreCase("HumanActor")
				|| type.equalsIgnoreCase("Role")
				|| type.equalsIgnoreCase("Artifact")
				|| type.equalsIgnoreCase("SystemActor")
				|| type.equalsIgnoreCase("Player")
				|| type.equalsIgnoreCase("System")
				|| type.equalsIgnoreCase("Actor")
				|| type.equalsIgnoreCase("ParticipationGroup")) {
			return true;
		}
		return false;
	}

	@Override
	public Collection<GraphNode> getLinks(GraphNode node, String type) {

		Collection<GraphNode> links = new HashSet();
		Collection<GraphNode> visited = new HashSet();
		visited.add(node);

		getDirectLinkedNodesAlsoInRelatedGroups(node, links, type, visited);
		// get containing links and process
		Collection<GraphNode> groups = new HashSet();

		getContainingGroupsTreetructure(node, groups);

		for (GraphNode group : groups) {
			getDirectLinkedNodesAlsoInRelatedGroups(group, links, type, visited);
		}
		return links;

	}

	public void getDirectLinkedNodesAlsoInRelatedGroups(GraphNode node,
			Collection<GraphNode> links, String type,
			Collection<GraphNode> visited) {
		Collection<GraphNode> directLinks = gdb.getDirectRelatedNodes(node);
		for (GraphNode link : directLinks) {
			if (visited.contains(link)) {
				continue;
			}
			visited.add(link);

			String ntype = link.getType();
			if (type == null || ntype.equals(type)) {
				links.add(link);
			}

			if (ntype.equalsIgnoreCase("ParticipationGroup")) {
				getContainedLinks(link, links, type);
			}

		}

		// directLinks = gdb.getContainedNodes(node);
		// for (Node link : directLinks) {
		// if (visited.contains(link)) {
		// continue;
		// }
		// visited.add(link);
		//
		// String ntype = (String) (link.getProperty("type"));
		// if (type == null || ntype.equals(type)) {
		// links.add(link);
		// }
		//
		// if (ntype.equalsIgnoreCase("ParticipationGroup")) {
		// getContainedLinks(link, links, type);
		// }
		//
		// }

	}

	protected void getContainingGroupsTreetructure(GraphNode node,
			Collection<GraphNode> groups) {
		String type = node.getType();
		Collection<GraphNode> containing = gdb.getContainingNodes(node);
		for (GraphNode link : containing) {
			if (groups.contains(link)) {
				continue;
			}

			groups.add(link);

			getContainingGroupsTreetructure(link, groups);
		}
	}

	protected void getContainedLinks(GraphNode node,
			Collection<GraphNode> links, String type) {
		Collection<GraphNode> contained = gdb.getContainedNodes(node);
		for (GraphNode link : contained) {
			if (links.contains(link)) {
				continue;
			}

			String ntype = link.getType();
			if (type == null || ntype.equals(type)) {
				links.add(link);
			}

			// links.add(link);
			String gtype = link.getType();
			if (gtype.equals("ParticipationGroup")) {
				getContainedLinks(link, links, type);
			}
		}
	}
}
